package com.example.baseapp.admin.service.impl;

import com.example.baseapp.admin.dto.resp.RoleMenuDto;
import com.example.baseapp.admin.dto.resp.RoleMenuMeta;
import com.example.baseapp.admin.entity.Menu;
import com.example.baseapp.admin.entity.RoleMenu;
import com.example.baseapp.admin.service.RoleMenuService;
import com.example.baseapp.admin.service.MenuService;
import com.example.baseapp.common.exception.BusinessException;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * RoleMenuHandle class
 *
 * @author zhangl
 * @date 2022/4/29 15:32
 */
@Component
public class RoleMenuHandle {
    @Resource
    private MenuService menuService;
    @Resource
    private RoleMenuService menuRoleService;

    /**
     * 根据角色获取菜单
     *
     * @param roleId 角色编号
     * @return 返回菜单实体
     */
    public List<RoleMenuDto> getRoleMenuRespByRoleId(String roleId) {
        List<RoleMenuDto> roleMenuDtoList = new ArrayList<>();

        //获取角色对应的菜单
        List<RoleMenu> roleMenuList = menuRoleService.getRoleMenuByRoleId(roleId);
        if (CollectionUtils.isEmpty(roleMenuList)) {
            throw BusinessException.createErrorException("获取失败.");
        }
        List<String> menuIdList = roleMenuList.stream().map(RoleMenu::getMenuId).collect(Collectors.toList());
        List<Menu> menuList = menuService.getMenuByMenuId(menuIdList);
        Map<String, List<Menu>> menuGroup = menuList.stream().collect(Collectors.groupingBy(Menu::getMenuParentId));
        //获取顶级菜单
        List<Menu> topMenuList = menuGroup.get("0000");
        topMenuList.forEach(menu -> {
            RoleMenuDto childrenNode = this.getRoleMenuDto(menu);
            List<RoleMenuDto> childrenByMenuRoleList = getChildrenByMenuRoleList(menu, menuGroup);
            childrenNode.setChildren(childrenByMenuRoleList);
            roleMenuDtoList.add(childrenNode);
        });
        return roleMenuDtoList;
    }

    /**
     * 循环获取菜单和子菜单
     *
     * @param menu      当前菜单
     * @param menuGroup 根据父菜单分组
     * @return List<RoleMenuDto> 角色对应菜单实体
     */
    private List<RoleMenuDto> getChildrenByMenuRoleList(Menu menu, Map<String, List<Menu>> menuGroup) {
        List<Menu> menuList = menuGroup.get(menu.getMenuId());
        List<RoleMenuDto> roleMenuDtoList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(menuList)) {
            for (Menu menuItem : menuList) {
                roleMenuDtoList.add(this.getRoleMenuDto(menuItem).setChildren(getChildrenByMenuRoleList(menuItem, menuGroup)));
            }
        }
        return roleMenuDtoList;
    }

    /**
     * Menu 转换为 Meta
     *
     * @param menu 菜单
     * @return 菜单信息
     */
    public RoleMenuMeta menuToRoleMenuMeta(Menu menu) {
        RoleMenuMeta roleMenuMeta = new RoleMenuMeta();
        roleMenuMeta.setTitle(menu.getTitle());
        roleMenuMeta.setIcon(menu.getIcon());
        roleMenuMeta.setIsAffix(menu.getIsAffix()  );
        roleMenuMeta.setIsHide(menu.getIsHide()  );
        roleMenuMeta.setIsIframe(menu.getIsIframe() );
        roleMenuMeta.setIsLink(menu.getLinkTo());
        roleMenuMeta.setIsKeepAlive(menu.getIsKeepAlive());
        List<String> roles = menuRoleService.getRoleIdByMenuId(menu.getMenuId());
        roleMenuMeta.setRoles(roles);
        return roleMenuMeta;
    }

    /**
     * 菜单menu实体转换为RoleMenuDto
     *
     * @param menu 菜单
     * @return RoleMenuDto
     */
    public RoleMenuDto getRoleMenuDto(Menu menu) {
        RoleMenuDto roleMenuDto = new RoleMenuDto();
        RoleMenuMeta meta = menuToRoleMenuMeta(menu);
        roleMenuDto.setMeta(meta);
        roleMenuDto.setComponent(menu.getComponentPath());
        roleMenuDto.setName(menu.getName());
        roleMenuDto.setPath(menu.getRouterPath());
        roleMenuDto.setIsLink(menu.getIsLink());
        roleMenuDto.setRedirect(menu.getRedirect());
        return roleMenuDto;
    }

    /**
     * 批量更新菜单权限关系表
     *
     * @param roleList 权限信息
     * @param menuId   菜单编号
     */
    public void updateRoleMenu(List<String> roleList, String menuId) {
        menuRoleService.delete(menuId);
        if (!CollectionUtils.isEmpty(roleList)) {
            List<RoleMenu> roleMenuList = roleList.stream().map(roleId -> {
                return new RoleMenu().setMenuId(menuId).setRoleId(roleId);
            }).collect(Collectors.toList());
            menuRoleService.insert(roleMenuList);
        }


    }
}
